package io.cici.cc.mybatis.lite.mapping;

import io.cici.cc.mybatis.lite.executor.keygen.Jdbc3KeyGenerator;
import io.cici.cc.mybatis.lite.executor.keygen.KeyGenerator;
import io.cici.cc.mybatis.lite.executor.keygen.NoKeyGenerator;
import io.cici.cc.mybatis.lite.session.Configuration;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * @author huihui
 */
@Slf4j
@Setter
@Getter
public final class MappedStatement {

    private String resource;
    private Configuration configuration;
    private String id;

    private SqlSource sqlSource;

    private ParameterMappings parameterMappings;
    private ResultMappings resultMappings;


    private SqlCommandType sqlCommandType;
    private KeyGenerator keyGenerator;
    private String[] keyProperties;
    private String[] keyColumns;


    private static String[] delimitedStringToArray(String in) {
        if (in == null || in.trim().length() == 0) {
            return null;
        }
        return in.split(",");
    }

    public Sql getSql(Object parameterObject) {
        Sql sql = sqlSource.getSql(parameterObject);
        List<ParameterMapping> parameterMappingList = sql.getParameterMappingList();
        if (parameterMappingList == null || parameterMappingList.isEmpty()) {
            sql = new Sql(configuration, sql.getSql(), this.parameterMappings.getParameterMappingList(), parameterObject);
        }

        return sql;
    }

    public static class Builder {
        private final MappedStatement mappedStatement = new MappedStatement();

        public Builder(Configuration configuration, String id, SqlSource sqlSource, SqlCommandType sqlCommandType) {
            mappedStatement.configuration = configuration;
            mappedStatement.id = id;
            mappedStatement.sqlSource = sqlSource;

            mappedStatement.parameterMappings = new ParameterMappings.Builder("defaultParameterMap", null, new ArrayList<>()).build();

            mappedStatement.sqlCommandType = sqlCommandType;
            mappedStatement.keyGenerator = configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType) ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE;

        }

        public Builder resource(String resource) {
            mappedStatement.resource = resource;
            return this;
        }

        public String id() {
            return mappedStatement.id;
        }

        public Builder parameterMap(ParameterMappings parameterMappings) {
            mappedStatement.parameterMappings = parameterMappings;
            return this;
        }

        public Builder resultMaps(ResultMappings resultMappings) {
            mappedStatement.resultMappings = resultMappings;

            return this;
        }

        public Builder keyGenerator(KeyGenerator keyGenerator) {
            mappedStatement.keyGenerator = keyGenerator;
            return this;
        }

        public Builder keyProperty(String keyProperty) {
            mappedStatement.keyProperties = delimitedStringToArray(keyProperty);
            return this;
        }

        public Builder keyColumn(String keyColumn) {
            mappedStatement.keyColumns = delimitedStringToArray(keyColumn);
            return this;
        }


        public MappedStatement build() {
            assert mappedStatement.configuration != null;
            assert mappedStatement.id != null;
            assert mappedStatement.sqlSource != null;


            return mappedStatement;
        }
    }

}
